package com.quectel.core.module.group.service.impl;


import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.quectel.core.module.group.dao.SysGroupRegionDao;
import com.quectel.core.module.group.dao.SysRegionVillageRefDao;
import com.quectel.core.module.group.dto.SysRegionVillageRefDto;
import com.quectel.core.module.group.entity.SysRegionVillageRefEntity;
import com.quectel.core.module.group.service.SysRegionVillageRefService;
import com.quectel.util.common.CopyUtils;
import com.quectel.util.kit.Snowflake;
import com.quectel.util.redis.RedisUtils;
import org.apache.dubbo.config.annotation.DubboService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import static com.quectel.core.constants.RedisCacheConstants.PROJECT_NAME;


/**
 * @author rananxin
 * @date 2020-07-27 10:14:58
 */
@DubboService
public class SysRegionVillageRefServiceImpl extends ServiceImpl<SysRegionVillageRefDao, SysRegionVillageRefEntity> implements SysRegionVillageRefService {

    private static final Logger LOGGER = LoggerFactory.getLogger(SysRegionVillageRefServiceImpl.class);
    /**
     * 区域权限懒加载
     */
    public static final String EXECUTE_REF_LOCK = PROJECT_NAME + "EXECUTE_REF_LOCK_";

    @Autowired
    private SysRegionVillageRefDao sysRegionVillageRefDao;
    @Autowired
    private SysGroupRegionDao sysGroupRegionDao;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteByGroupId(Long groupId) {
        sysRegionVillageRefDao.delete(new LambdaQueryWrapper<SysRegionVillageRefEntity>().eq(SysRegionVillageRefEntity::getSysGroupId, groupId));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void executeRef(Long sysGroupId) {
        boolean setnx = RedisUtils.setnx(EXECUTE_REF_LOCK + sysGroupId, String.valueOf(sysGroupId), 5, TimeUnit.MINUTES);
        if (setnx) {
            deleteByGroupId(sysGroupId);
            Set<Long> villageIds = sysGroupRegionDao.queryVillageIds(sysGroupId);
            List<SysRegionVillageRefEntity> list = new ArrayList<>();
            for (Long villageId : villageIds) {
                SysRegionVillageRefEntity sysRegionVillageRefEntity = new SysRegionVillageRefEntity();
                sysRegionVillageRefEntity.setId(Snowflake.nextId());
                sysRegionVillageRefEntity.setSysGroupId(sysGroupId);
                sysRegionVillageRefEntity.setVillageId(villageId);
                list.add(sysRegionVillageRefEntity);
            }
            if (CollectionUtil.isNotEmpty(list)) {
                super.saveBatch(list);
            }
        }
    }

    @Override
    public List<SysRegionVillageRefDto> queryList(Map<String, Object> params) {
        List<SysRegionVillageRefEntity> list = sysRegionVillageRefDao.queryList(params);
        return CopyUtils.copyList(list, SysRegionVillageRefDto.class);
    }

    @Override
    public int queryTotal(Map<String, Object> params) {
        return sysRegionVillageRefDao.queryTotal(params);
    }

    @Override
    public Long save(SysRegionVillageRefDto dto) {
        SysRegionVillageRefEntity entity = CopyUtils.copyObj(dto, SysRegionVillageRefEntity.class);
        entity.setId(Snowflake.nextId());
        sysRegionVillageRefDao.insert(entity);
        return entity.getId();
    }

    @Override
    public void updateById(SysRegionVillageRefDto dto) {
        SysRegionVillageRefEntity entity = CopyUtils.copyObj(dto, SysRegionVillageRefEntity.class);
        sysRegionVillageRefDao.updateById(entity);
    }

    @Override
    public SysRegionVillageRefDto selectById(Long id) {
        SysRegionVillageRefEntity entity = sysRegionVillageRefDao.selectById(id);
        return CopyUtils.copyObj(entity, SysRegionVillageRefDto.class);
    }

    @Override
    public void deleteById(Long id) {
        sysRegionVillageRefDao.deleteById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteBatch(Long[] ids) {
        for (Long id : ids) {
            deleteById(id);
        }
    }
}
